package com.encryption.controls
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.text.TextLineMetrics;
	
	import mx.containers.Form;
	import mx.containers.FormItem;
	import mx.controls.Label;
	import mx.controls.TextInput;
	import mx.core.EdgeMetrics;
	import mx.core.IFlexDisplayObject;
	import mx.core.IUIComponent;
	import mx.core.mx_internal;
	import mx.utils.StringUtil;
	
	use namespace mx_internal;
	
	[Style(name="inputWidth", type="Number", format="Length")]
	
	[Event(name="inputFocusOut", type="flash.events.Event" )]
	
	public class AdvancedFormItem extends FormItem
	{
		private var indicatorObj:IFlexDisplayObject;
		private var _input:TextInput;
		private var _errorToolTip:Label;
		private var _errorToolTipText:String = "";
		private var _inputPassword:Boolean = false;
		private var _inputEditable:Boolean = true;
		private var _inputEnabled:Boolean = true;
		private var _inputRestrict:String = null;
		private var _inputMaxChars:int = 100;
		
		public function AdvancedFormItem()
		{
			super();
			
			setStyle("inputWidth", 200);
			setStyle("indicatorGap", 3);
			direction = "horizontal";
		}
		
		override protected function createChildren():void
		{
			super.createChildren();
			
			if(_input == null){
				_input = new TextInput();
				var inputWidth:Number = getStyle("inputWidth"); 
				_input.width = inputWidth;
				_input.displayAsPassword = _inputPassword;
				_input.restrict = _inputRestrict;
				_input.maxChars = _inputMaxChars;
				_input.editable = _inputEditable;
				_input.enabled = _inputEnabled;
				_input.addEventListener(FocusEvent.FOCUS_OUT, inputFocusOutHandle);
				
				addChild(_input);
			}
			
			if(_errorToolTip == null){
				_errorToolTip = new Label();
				_errorToolTip.text = _errorToolTipText;
				_errorToolTip.setStyle("color",0xFE0F0F);
				
				addChild(_errorToolTip);
			}
		}
		
		public function set inputPassword(value:Boolean):void
		{
			if(_inputPassword != value){
				_inputPassword = value;
				if(_input != null)
					_input.displayAsPassword = _inputPassword;
			}
		}
		
		public function set errorToolTip(value:String):void
		{
			if(_errorToolTipText != value){
				_errorToolTipText = value;
				if(_errorToolTip != null)
					_errorToolTip.text = value;
			}
		}
		
		public function set inputEditable(value:Boolean):void
		{
			if(_inputEditable != value){
				_inputEditable = value;
				if(_input != null)
					_input.editable = _inputEditable;
			}
		}
		
		public function set inputEnabled(value:Boolean):void
		{
			if(_inputEnabled != value){
				_inputEnabled = value;
				if(_input != null)
					_input.enabled = _inputEnabled;
			}
		}
		
		public function set inputMaxChars(value:int):void
		{
			if(_inputMaxChars != value){
				_inputMaxChars = value;
				if(_input != null)
					_input.maxChars = value;
			}
		}
		
		public function get errorToolTip():String
		{
			if(_errorToolTip != null){
				return _errorToolTip.text;
			}
			return "";
		}	
		
		public function set infoToolTip(value:String):void
		{
			
		}
		
		public function set inputRestrict(value:String):void
		{
			if(_inputRestrict != value){
				_inputRestrict = value;
				if(_input != null)
					_input.restrict = _inputRestrict;
			}
		}
		
		public function get inputText():String{
			return _input != null ? _input.text : "";
		}
		
		public function set inputText(value:String):void
		{
			if(_input)
				_input.text = value;
		}
		
		public function get trimInputText():String{
			return StringUtil.trim(inputText);
		}
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			
			// Position our label now that our children have been positioned.
			// Moving our children can affect the baselinePosition. (Bug 86725)
			var vm:EdgeMetrics = viewMetricsAndPadding;
			
			// we have x,y with respect to viewMetricsAndPadding here b/c
			// labelObj is added to rawChildren.  The children of FormItem
			// are added to a container object, so start at paddingLeft
			// and paddingTop (as the containerObj has border around it)
			var x:Number = vm.left;
			var y:Number = vm.top;
			
			var labelWidth:Number = calculateLabelWidth();
			
			var child:IUIComponent;
			var childBaseline:Number;
			
			// Position our label.
			if (numChildren > 0)
			{
				// Center label with first child
				child = getLayoutChildAt(0);
				childBaseline = child.baselinePosition;
				if (!isNaN(childBaseline))
					y += childBaseline - itemLabel.baselinePosition;
			}
			
			// Set label size.
			itemLabel.setActualSize(labelWidth, itemLabel.getExplicitOrMeasuredHeight());
			itemLabel.move(x, y);
			
			x += labelWidth;
			
			// Position the "required" indicator.
			displayIndicator(x, y);
		
		}
		
		/**
		 *  @private
		 */
		private function calculateLabelWidth():Number
		{
			var labelWidth:Number = getStyle("labelWidth");
			
			// labelWidth of 0 is the same as NaN
			if (labelWidth == 0)
				labelWidth = NaN;
			
			if (isNaN(labelWidth) && parent is Form)
				labelWidth = AdvancedForm(parent).calculateLabelWidth();
			
			if (isNaN(labelWidth))
				labelWidth = getPreferredLabelWidth();
			
			return labelWidth;
		}
		
		/**
		 *  @private
		 */
		public function getPreferredLabelWidth():Number
		{
			if (!label || label == "")
				return 0;
			
			if (isNaN(itemLabel.measuredWidth))
				itemLabel.validateSize();
			
			var labelWidth:Number = itemLabel.measuredWidth;
			
			if (isNaN(labelWidth))
				return 0;
			
			return labelWidth;
		}
		
		/**
		 *  @private
		 */
		private function displayIndicator(xPos:Number, yPos:Number):void
		{
			if (!indicatorObj)
			{
				var indicatorClass:Class = getStyle("indicatorSkin") as Class;
				indicatorObj = IFlexDisplayObject(new indicatorClass());
				rawChildren.addChild(DisplayObject(indicatorObj));
			}
			var m:TextLineMetrics = itemLabel.measureText(itemLabel.text);
			
			indicatorObj.x =
				xPos - getStyle("indicatorGap") - indicatorObj.width - m.width - 2;
			
			if (itemLabel)
			{
				indicatorObj.y = yPos +
					(itemLabel.getExplicitOrMeasuredHeight() -
						indicatorObj.measuredHeight) / 2;
				
				itemLabel.x = itemLabel.x - getStyle("indicatorGap") + indicatorObj.width;
				itemLabel.y = 2;
			}
		}
		
		private function inputFocusOutHandle(event:FocusEvent):void
		{
			if(trimInputText == ""){
				errorToolTip = "请填写" + label.substring(0, label.length - 1);
			}else{
				errorToolTip = "";
			}
			dispatchEvent(new Event("inputFocusOut"));
		}
	}
}